﻿using System;
using System.Collections.Generic;
using NUnit.Framework;
using starLiGHT.Collections;
using Microsoft.Xna.Framework;

namespace starLiGHT.Engine.Tests
{
    [TestFixture]
    public class CircularBuffer
    {
        CircularBuffer<int> buffer;

        [SetUp]
        public void Init()
        {
            buffer = new CircularBuffer<int>(5);
        }

        [Test]
        public void Constructor01()
        {
            Assert.AreEqual(5, buffer.Capacity);
            buffer = new CircularBuffer<int>(100);
            Assert.AreEqual(100, buffer.Capacity);
        }

        [Test]
        public void Fill01()
        {
            buffer.Put(1);
            Assert.AreEqual(1, buffer.Count);
            buffer.Put(2);
            Assert.AreEqual(2, buffer.Count);
            buffer.Put(3);
            Assert.AreEqual(3, buffer.Count);
            buffer.Put(4);
            Assert.AreEqual(4, buffer.Count);
            buffer.Put(5);
            Assert.AreEqual(5, buffer.Count);

            Assert.AreEqual(1, buffer.Get(0));
            Assert.AreEqual(2, buffer.Get(1));
            Assert.AreEqual(3, buffer.Get(2));
            Assert.AreEqual(4, buffer.Get(3));
            Assert.AreEqual(5, buffer.Get(4));
        }

        [Test]
        public void Fill02()
        {
            for (int i = 1; i <= 6; i++)
            {
                buffer.Put(i);
            }

            Assert.AreEqual(5, buffer.Count);

            for (int i = 2; i <= 6; i++)
            {
                Assert.AreEqual(i, buffer.Get(i - 2));
            }
        }

        [Test]
        public void Fill03()
        {
            for (int i = 1; i <= 30; i++)
            {
                buffer.Put(i);
            }

            Assert.AreEqual(5, buffer.Count);

            for (int i = 26; i <= 30; i++)
            {
                Assert.AreEqual(i, buffer.Get(i - 26));
            }
        }

        [Test]
        public void Clear01()
        {
            for (int i = 1; i <= 30; i++)
            {
                buffer.Put(i);
            }

            Assert.AreEqual(5, buffer.Count);

            buffer.Clear();

            Assert.AreEqual(0, buffer.Count);
        }

        [Test]
        public void Enumerator01()
        {
            for (int i = 1; i <= 5; i++)
            {
                buffer.Put(i);
            }

            Assert.AreEqual(5, buffer.Count);

            int expected = 1;
            foreach (int actual in buffer)
            {
                Assert.AreEqual(expected++, actual);
            }
        }

        [Test]
        public void Enumerator02()
        {
            for (int i = 1; i <= 9; i++)
            {
                buffer.Put(i);
            }

            Assert.AreEqual(5, buffer.Count);

            int expected = 5;
            foreach (int actual in buffer)
            {
                Assert.AreEqual(expected++, actual);
            }
        }

        [Test]
        //[ExpectedException("System.ArgumentOutOfRangeException")]
        public void CapacityExceeded01()
        {
            buffer[0] = 1;
            int value = buffer.Get(5);
            Assert.AreEqual(1, value);
        }

        [Test]
        public void CapacityExceeded02()
        {
            buffer[0] = 1;
            int value = buffer[5];
            Assert.AreEqual(1, value);
        }

        [Test]
        public void CapacityExceeded03()
        {
            buffer[5] = 42;

            Assert.AreEqual(42, buffer.Get(5));
            Assert.AreEqual(42, buffer.Get(0));
        }

        [Test]
        public void CapacityExceeded04()
        {
            buffer[-1] = 42;

            Assert.AreEqual(42, buffer.Get(4));
            Assert.AreEqual(42, buffer.Get(-1));
        }

        [Test]
        public void Indexer01()
        {
            for (int i = 0; i < 5; i++)
                buffer[i] = i + 1;

            for (int i = 0; i < 5; i++)
                Assert.AreEqual(i + 1, buffer[i]);
        }

        [Test]
        public void Indexer02()
        {
            buffer[5] = 42;

            Assert.AreEqual(42, buffer[5]);
            Assert.AreEqual(42, buffer[0]);
        }

        [Test]
        public void Indexer03()
        {
            buffer[4] = 42;

            Assert.AreEqual(42, buffer[4]);
            Assert.AreEqual(42, buffer[-1]);
        }

        [Test]
        public void Indexer04()
        {
            buffer[-1] = 42;

            Assert.AreEqual(42, buffer[4]);
            Assert.AreEqual(42, buffer[-1]);
        }

        [Test]
        public void Indexer05()
        {
            for (int i = 5; i < 10; i++)
                buffer[i] = i - 5;

            for (int i = 0; i < 5; i++)
                Assert.AreEqual(i, buffer[i]);
        }

        [Test]
        public void Initialize01()
        {
            buffer.Initialize(42);

            foreach (int v in buffer)
            {
                Assert.AreEqual(42, v);
            }
        }

    }
}